Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clamp teleportation position #4203

Merged
merged 5 commits into from Mar 20, 2020
Merged

Clamp teleportation position #4203

merged 5 commits into from Mar 20, 2020

Conversation

stone3311
Copy link
Contributor

A large position value would lead to a rounding error in the noise generator which uses float instead of double. A position greater than 0x08000000 * 16 would also lead to a failed assertion in cWorldStorage::QueueLoadChunk. The clamping could be done in cEntity:SetPosition for extra safety, but that might impact performance. This fixes #4077

@bearbin
Copy link
Member

bearbin commented Apr 2, 2018

My feeling here would be that simply rejecting a teleport request would be better than clamping the coordinates. I think adding a check in SetPosition as well would be a good idea - just clamping a float is not really the most intensive operation.

// This is necessary to avoid rounding errors in the noise generator and overflows in the chunk loader
const double ClampedPosX = Clamp(a_PosX, -167770000.0, 167770000.0);
const double ClampedPosY = Clamp(a_PosY, -167770000.0, 167770000.0);
const double ClampedPosZ = Clamp(a_PosZ, -167770000.0, 167770000.0);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I want at least a constant for these numbers.
If you could represent them with std::numeric_limits, it would be even better 😄 .

P.S.: Maybe also just update the a_Pos(X|Y|Z) variables to prevent anyone mixing the clamped and non clamped versions.

// Clamp the positions to exactly representable single-precision floating point values
// This is necessary to avoid rounding errors in the noise generator and overflows in the chunk loader
const double ClampedPosX = Clamp(a_PosX, -167770000.0, 167770000.0);
const double ClampedPosY = Clamp(a_PosY, -167770000.0, 167770000.0);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't make that much sense.
You could for example teleport to y = -167770000 and then the falling mechanics should get us into bad numbers.
Clamp it to 0 - MAX_HEIGHT makes a lot more sense.

@bibo38
Copy link
Contributor

bibo38 commented Apr 5, 2018

The clamping could be done in cEntity:SetPosition for extra safety, but that might impact performance.

See The Rules of Code Optimization.
Since the clamping operation is basically a condition (is value smaller/greater than clamped value), the processor will automatically optimize this using branch prediction. Because the value is most of the times inside the clamped area, the processor can create a very good prediction. Thus it shouldn't be a performance issue.

Otherwise you could just add an ASSERT or an if(outside) { throw "out of bounds" } construct, if you expect the callers of SetPosition to provide valid/clamped values.

@madmaxoft madmaxoft merged commit 0a1cfda into cuberite:master Mar 20, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Server crashes if player is far outside the world
6 participants